/**
 * 
 */
package org.pjsip.pjsua2.app;

import org.pjsip.pjsua2.ALVoipWorkingStateCallback;
import org.pjsip.pjsua2.app.exception.ALVoipException;

import android.text.TextUtils;

import com.alstudio.utils.log.ALLog;

/**
 * voip管理器，提供初始化voip模块、关闭模块，与rtp服务器交互、与远端用户打洞，传输语音，停止语音的api
 * 
 * @author alonso lee
 * 
 */
public class ALVoipManager {

	// 本地udp端口
	private final int LOCAL_PORT = 4000;

	private static ALVoipWorkingStateCallback alVoipWorkingStateCallback;

	/**
	 * @param alVoipWorkingStateCallback
	 *            the alVoipWorkingStateCallback to set
	 */
	public static void setAlVoipWorkingStateCallback(
			ALVoipWorkingStateCallback alVoipWorkingStateCallback) {
		ALVoipManager.alVoipWorkingStateCallback = alVoipWorkingStateCallback;
	}

	/**
	 * @return the alVoipWorkingStateCallback
	 */
	public static ALVoipWorkingStateCallback getAlVoipWorkingStateCallback() {
		return alVoipWorkingStateCallback;
	}

	/**
	 * 注册启动voip模块
	 */
	public static void registerVoipModule() {
		MyApp.ep.init_voiplib();
	}

	/**
	 * 关闭voip模块
	 */
	public static void unRegisterVoipModule() {
		MyApp.ep.release_voiplib();
	}

	/**
	 * 向rtp服务器上传本地内网ip地址，网络类型、本地udp端口、应用程序登陆的账号（纯id）
	 * 
	 * @param data
	 *            由应用程序登陆的账号（纯id）&本地内网ip地址&本地udp端口&网络类型拼装的数据包。如
	 *            '&200281&192.168.1.121&4000&wifi'
	 * @param serverIp
	 *            rtp服务器地址
	 * @param serverPort
	 *            rtp服务器端口
	 */
	public static void postUdpDataToServer(PostToRtpServerData data) {

		// 检查传入的参数是否正确
		checkPostToRtpServerData(data);

		// 由应用程序登陆的账号（纯id）&本地内网ip地址&本地udp端口&网络类型拼装的数据包。如
		// '&200281&192.168.1.121&4000&wifi'。所带英文字符为小写
		String postData = "&" + data.getUserId() + "&" + data.getLocalIp()
				+ "&" + data.getLocalPort() + "&" + data.getNetworkType();
		postData = postData.toLowerCase();
		ALLog.d("传输数据到rtp服务器: " + postData);
		MyApp.ep.do_nat(data.getRtpServerIp(),data.getRtpServerPort(), postData);

	}

	/**
	 * 与通话用户进行打洞工作。根据data中带有的nat、lan、turn地址，发送的数据位当前通话的sessionid
	 * 
	 * @param data
	 *            从此对象可取得通话对方的nat、lan、turn地址。得到sessionid，传送给对方
	 */
	public static void postUdpDataToRemoteUser(PostToRemoteUserData data) {
		checkPostToRemoteUserData(data);

		MyApp.ep.do_negotiate_to_remote_target(data.getLanIp(),
				data.getLanPort(), data.getNatIp(), data.getNatPort(),
				data.getTransferIp(), data.getTransferPort(),
				data.getVoipSession());
		ALLog.d("开始打洞");
	}

	/**
	 * 传送语音到指定ip、端口
	 * 
	 * @param ip
	 *            待传输语音的ip
	 * @param port
	 *            待传输语音的端口
	 */
	public static void startStream(String ip, int port,String codec) {
		MyApp.ep.start_stream(ip, port,codec);
	}

	/**
	 * 停止发送语音
	 */
	public static void stopStream() {
		MyApp.ep.stop_stream();
	}

	public void makeCall() {

	}

	/**
	 * 检查与rtp服务器交互数据是否正确
	 * 
	 * @param data
	 */
	private static void checkPostToRtpServerData(PostToRtpServerData data) {
		// 检查传入的data对象是否为空
		if (data == null) {
			throw new NullPointerException("PostToRtpServerData data 不能为null");
		}

		// 检查rtp服务器是否为空
		if (TextUtils.isEmpty(data.getRtpServerIp())) {
			throw new ALVoipException("RtpServer 无效");
		}

		// 检查rtp服务器端口是否无效
		if (data.getRtpServerPort() == -1) {
			throw new ALVoipException("RtpServer 无效");
		}

		// 检查传入的user id是否有效
		if (TextUtils.isEmpty(data.getUserId())) {
			throw new ALVoipException("传入的用户id 无效");
		}
	}

	/**
	 * 检查与远端用户打洞数据是否正确
	 * 
	 * @param data
	 */
	private static void checkPostToRemoteUserData(PostToRemoteUserData data) {
		if (data == null) {
			throw new NullPointerException("post to remote user data 不能为null");
		}
		if (TextUtils.isEmpty(data.getVoipSession()))
			throw new NullPointerException("当前会话id不能为null");
	}

}
